package com.yc.atm;

import org.apache.log4j.Logger;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class BankServer {
    private static Logger log = Logger.getLogger(BankServer.class.getName());//创建日志
    public static void main(String[] args) throws IOException {
        //自己电脑的核数
        int processors= Runtime.getRuntime().availableProcessors();
        //核心线程池的大小
        int corePoolSize = processors;
        //核心线程池的最大线程数
        int maxPoolSize = corePoolSize*2;
        //线程最大空闲时间
        long keepAliveTime = 10;
        //时间单位
        TimeUnit unit = TimeUnit.SECONDS;  //enum枚举  常量
        //有界阻塞队列  容量为2 最多允许放入两个空闲任务
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(200);  //同时最大任务量为 7  超过7个任务  则执行拒绝
        //线程创建工厂
        ThreadFactory threadFactory = new NameThreadFactory();
        //线程池拒绝策略
        RejectedExecutionHandler handler = new MyIgnorePolicy();
        //*********线程池执行器
        ThreadPoolExecutor executor = null;
        //推荐的创建线程池的方法  不推荐使用现成的API创建线程池
        executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        //预启动所有核心线程  提升效率
        executor.prestartAllCoreThreads();


        Bank b = new Bank();
        ServerSocket ss = new ServerSocket(10082);
        log.info("银行服务器启动，监听"+ss.getLocalPort()+"端口");
        boolean flag =true;
        while(flag){
            Socket s=ss.accept();
            System.out.println("Atm客户端"+s.getRemoteSocketAddress()+"登录了服务器");
            //TODO：商业项目必须用线程池”


            BankTask task = new BankTask(s, b);
            executor.submit(task);//提交任务到线程池

        }
        executor.shutdown();

    }


    /***
     * 线程工厂
     */
    static class NameThreadFactory implements ThreadFactory {
        //线程id       AtomicInteger 原子类      原子整型类
        //原子 可见 有序
        private final AtomicInteger threadId=new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable runnable) {
            Thread t= new Thread(runnable,"线程-"+threadId.getAndIncrement());
//            System.out.println(t.getName()+"已经被创建");
            return t;
        }
    }


    //线程池拒绝策略
    public static class MyIgnorePolicy implements RejectedExecutionHandler {
        private Logger log = Logger.getLogger(MyIgnorePolicy.class.getName());
        @Override                      //被拒绝的任务                 线程池对象
        public void rejectedExecution(Runnable runnable, ThreadPoolExecutor e) {
            doLog(runnable,e);
        }
        private void doLog(Runnable runnable,ThreadPoolExecutor e){
            //可做日志记录等
            log.error("线程池："+e.toString()+runnable.toString()+"被拒绝执行");
        }
    }
}


